﻿#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //图形显示区域大小
    displayRect = QRect(0,0,100,100);
    scene = new QGraphicsScene(this);
    ui->graphicsView->setScene(scene);
    view = ui->graphicsView;
    view->setSceneRect(displayRect);

    //按钮设置功能
    ui->tbnRole->setRole(mainRole);
    ui->tbnWall->setRole(wall);
    ui->tbnBox->setRole(box);
    ui->tbnBoxReq->setRole(boxReq);
    ui->tbnGarbage->setRole(garbage);

    connect(ui->tbnGarbage,&MyToolButton::sendDelete,
            this,&MainWindow::reciveGarbageDel);

    //布置文件名
    fileLabel = new QLabel(this);
    ui->statusBar->addWidget(fileLabel);

    timerId = startTimer(100);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_actionStart_triggered()
{
    bool isok = false;
    int result = QInputDialog::getInt(this,"请输入地图尺寸","格子数:"
                                      ,10,5,20,1,&isok);
    if(isok == false)
        return;

    mRole = nullptr;
    filePath.clear();
    initUi(result);

    gridNumbers = result;
    isStart = true;
    ui->tbnRole->setEnabled(isStart);
    ui->tbnWall->setEnabled(isStart);
    ui->tbnBox->setEnabled(isStart);
}

//初始化界面，格子数
void MainWindow::initUi(int grids)
{
    scene->clear();
    vectorGround.clear();

    int width = displayRect.width();
    int height = displayRect.height();

    int min = (width>height)?height:width;

    scene->setSceneRect(displayRect);

    qreal widWidth = view->width();
    qreal widHeight = view->height();
    qreal widMin = (widWidth>widHeight)?widHeight:widWidth;
    view->scale(1.0/hasScaled,1.0/hasScaled);
    double scale = widMin/100;
    view->scale(scale,scale);
    hasScaled = scale;

    QRect rect(5,5,min-10,min-10);
    double onewidth = (min-20.0)/grids;
    mWidth = onewidth;

    QGraphicsRectItem* item = new QGraphicsRectItem(rect);

    scene->addItem(item);

    //绘制棋盘格
    for (int col=0;col<grids;col++) {
        QVector<MyGrid*> onegrid;
        for (int row=0;row<grids;row++) {
            MyGrid* pix = new MyGrid(onewidth,&listRole,0);
            pix->setPos(10+onewidth*col,10+onewidth*row);
            pix->setPoint(col,row);
            scene->addItem(pix);
            onegrid.append(pix);
            connect(pix,&MyGrid::sendPoi,this,&MainWindow::recivePoi);
        }
        vectorGround.append(onegrid);
    }
    //将主角绘制出来
    mRole = new MyMainRole(onewidth,0);
    mRole->setPos(1.123,1.123);
    scene->addItem(mRole);
    connect(mRole,&MyMainRole::sendGarbageDisplay,this,&MainWindow::reciveGarbageDis);

    listRole.clear();
    listRole.append(mRole);

    saveSize = this->size();
}

//检查保存内容是否合格
bool MainWindow::checkDataIsQua()
{
    if(isStart == false)
    {
        QMessageBox::information(this,"提示","未创建或打开文件");
        return false;
    }
    if(mRole->isVisible() == false)
    {
        QMessageBox::information(this,"提示","主角未创建");
        return false;
    }
    if(ui->tbnBoxReq->isEnabled() == true)
    {
        QMessageBox::information(this,"提示","箱子和箱子目的地数量不匹配");
        return false;
    }

    int boxNumbers = 0;
    foreach(auto* role,listRole)
    {
        if(role->getState() == 2)
        {
            boxNumbers++;
        }
    }
    if(boxNumbers==0)
    {
        QMessageBox::information(this,"提示","箱子数量不能未0");
        return false;
    }

    return true;
}

void MainWindow::freshTBNBoxDisplay()
{
    int boxCount=0;
    int boxReqCount=0;
    foreach(auto* role,listRole)
    {
        if(role->getState() == 2)
        {
            boxCount++;
        }
        else if(role->getState() == 1)
        {
            boxReqCount++;
        }
    }
    if(boxCount <= boxReqCount)
    {
        ui->tbnBox->setEnabled(true);
        ui->tbnBoxReq->setEnabled(false);
    }
    else {
        ui->tbnBox->setEnabled(false);
        ui->tbnBoxReq->setEnabled(true);
    }
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    Q_UNUSED(event);
}

void MainWindow::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == timerId)
    {
        if(isStart == true)
        {
            if(saveSize != this->size())
            {
                qreal widWidth = view->width();
                qreal widHeight = view->height();
                qreal widMin = (widWidth>widHeight)?widHeight:widWidth;
                view->scale(1.0/hasScaled,1.0/hasScaled);
                double scale = widMin/100;
                view->scale(scale,scale);
                hasScaled = scale;
                saveSize = this->size();
            }
        }
    }
}

//接受内容
void MainWindow::recivePoi(int recIndex, QPoint point,bool isHide)
{

    //如果是主角的内容
    if(recIndex == 0)
    {
        if(isHide)
        {
            if(mRole->pos() == vectorGround[point.x()][point.y()]->pos())
                mRole->hide();
        }
        else {
            mRole->setPos(vectorGround[point.x()][point.y()]->pos());
            mRole->setPoint(point.x(),point.y());
            mRole->show();
        }
    }
    //放置物体
    else if((recIndex == 1)||(recIndex == 2)||(recIndex == 3))
    {
        MyMainRole* role = new MyMainRole(mWidth,recIndex);
        scene->addItem(role);
        listRole.append(role);
        role->setPos(vectorGround[point.x()][point.y()]->pos());
        role->setPoint(point.x(),point.y());
        role->show();
        connect(role,&MyMainRole::sendGarbageDisplay,this,&MainWindow::reciveGarbageDis);
        freshTBNBoxDisplay();
    }

}

//垃圾桶何时显示
void MainWindow::reciveGarbageDis(bool display)
{
    ui->tbnGarbage->setEnabled(display);
}

//接受垃圾桶要删除的信息,删除是在矩阵的坐标点位
void MainWindow::reciveGarbageDel(QPoint del)
{
    int count = listRole.count();
    for (int index = 0; index < count ;index++) {
        if(listRole[index]->getPoint() == del)
        {
            int role = listRole[index]->getState();
            if(role == 0)
            {//如果是主角就隐藏主角
                mRole->hide();
                break;
            }
            else
            {
                listRole[index]->deleteLater() ;
                listRole.removeAt(index);
                //刷新显示
                freshTBNBoxDisplay();
                break;
            }
        }
    }
}

//保存内容
void MainWindow::on_actionSave_triggered()
{
    //检查保存内容是否合格
    if(checkDataIsQua() == false)
    {
        return;
    }

    if(filePath.isEmpty() == true)
    {
        QFileInfo info(QCoreApplication::applicationFilePath());
        QString path = info.path();
        filePath = QFileDialog::getSaveFileName(this,"请选择保存位置",path,"*.json");
        if(filePath.isEmpty())
            return;
    }
    fileLabel->setText(filePath);
    QJsonDocument doc;
    QJsonObject obj;

    QJsonArray array;
    foreach(MyMainRole* role,listRole)
    {
        array.append(role->toJson());
    }

    obj.insert("gridNumbers",gridNumbers);
    obj.insert("roles",array);

    doc.setObject(obj);

    QFile file(filePath);
    if(file.open(QIODevice::WriteOnly|QIODevice::Text))
    {
        QTextStream stream(&file);
        file.write(doc.toJson());
    }
    file.close();
}

void MainWindow::on_actionLoad_triggered()
{
    QFileInfo info(QCoreApplication::applicationFilePath());
    QString path = info.path();
    QString getPath = QFileDialog::getOpenFileName(this,"请选择文件位置",path,"*.json");

    if(getPath.isEmpty() == true)
        return;

    int result = 0;
    QJsonArray array;
    QFile file(getPath);
    if(file.open(QIODevice::ReadOnly|QIODevice::Text))
    {
        QJsonDocument doc;
        QByteArray bytes = file.readAll();
        doc = QJsonDocument::fromJson(bytes);
        file.close();

        QJsonObject obj = doc.object();
        result = obj.value("gridNumbers").toInt();
        if(result == 0)
        {
            QMessageBox::warning(this,"提示","该文件格子数不正确");
            return;
        }
        array = obj.value("roles").toArray();
        int mainRCount=0,boxCount=0,boxReqCount=0;
        foreach(auto mobj,array)
        {
            int roleState = mobj.toObject().value("mrole").toInt();
            switch (roleState) {
            case 0:mainRCount++;break;
            case 1:boxReqCount++;break;
            case 2:boxCount++;break;
            }
        }
        if(mainRCount != 1)
        {
            QMessageBox::warning(this,"提示","该文件主角数量不正确");
            return;
        }
        if((boxReqCount != boxCount)||(boxCount == 0))
        {
            QMessageBox::warning(this,"提示","箱子数量不正确");
            return;
        }
    }
    filePath = getPath;
    fileLabel->setText(filePath);
    initUi(result);

    foreach(auto mobj,array)
    {
        int roleState = mobj.toObject().value("mrole").toInt();
        int mx = mobj.toObject().value("mx").toInt();
        int my = mobj.toObject().value("my").toInt();
        switch (roleState) {
            case 0:
            {
                mRole->setPos(vectorGround[mx][my]->pos());
                mRole->setPoint(mx,my);
                mRole->show();
                break;
            }
            case 1:
            case 2:
            case 3:
            {
                MyMainRole* role = new MyMainRole(mWidth,roleState);
                scene->addItem(role);
                listRole.append(role);
                role->setPos(vectorGround[mx][my]->pos());
                role->setPoint(mx,my);
                role->show();
                connect(role,&MyMainRole::sendGarbageDisplay,this,&MainWindow::reciveGarbageDis);
                break;
            }
        }
    }



    gridNumbers = result;
    isStart = true;
    ui->tbnRole->setEnabled(isStart);
    ui->tbnWall->setEnabled(isStart);
    ui->tbnBox->setEnabled(isStart);
}
